/**
 * @file compiler.h
 * @brief VimL编译器 - 支持调试信息生成
 * @author VimLVM Team
 * @date 2025
 */

#pragma once

#include "viml/instruction.h"
#include "viml/value.h"
#include "viml/debugger.h"
#include "viml/optimizer.h"
#include <memory>
#include <vector>
#include <string>
#include <unordered_map>

namespace viml {

/**
 * @brief 编译结果
 */
struct CompileResult {
    std::shared_ptr<Function> function;
    std::vector<std::string> errors;
    bool success = false;
};

/**
 * @brief 控制流语句信息
 */
struct IfInfo {
    size_t jump_pos;
    bool has_else;
};

struct WhileInfo {
    size_t loop_start;
    size_t jump_pos;
    std::string condition;  // 条件表达式
    size_t cond_reg;      // 条件结果寄存器
};

/**
 * @brief for循环语句信息
 */
struct ForInfo {
    size_t loop_start;      // 循环开始位置
    size_t jump_pos;        // 条件跳转位置
    std::string var_name;   // 循环变量名
    size_t list_reg;        // 列表寄存器
    size_t index_reg;       // 索引寄存器
    size_t len_reg;         // 长度寄存器
    size_t item_reg;        // 当前项寄存器
};

/**
 * @brief 编译上下文
 */
struct CompileContext {
    std::string source_name;
    std::vector<std::string> source_lines;
    std::unordered_map<std::string, size_t> constants;
    std::vector<Value> constant_pool;
    std::shared_ptr<DebugInfo> debug_info;
    std::shared_ptr<Function> function;
    std::unordered_map<std::string, size_t> variable_registers; ///< 变量到寄存器的映射
    size_t next_register = 0;
    std::vector<IfInfo> if_stack;           ///< if语句栈
    std::vector<WhileInfo> while_stack;     ///< while语句栈
    std::vector<ForInfo> for_stack;           ///< for循环栈
    
    CompileContext(const std::string& name) 
        : source_name(name), debug_info(std::make_shared<DebugInfo>()) {}
};

/**
 * @brief VimL编译器
 */
class Compiler {
public:
    Compiler();
    ~Compiler() = default;
    
    /**
     * @brief 编译源代码
     */
    CompileResult compile(const std::string& source, const std::string& filename = "<script>");
    
private:
    /**
     * @brief 词法分析
     */
    std::vector<std::string> tokenize(const std::string& source);
    
    /**
     * @brief 编译let语句
     */
    bool compile_let_statement(const std::string& stmt, CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 编译echo语句
     */
    bool compile_echo_statement(const std::string& stmt, CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 编译表达式语句
     */
    bool compile_expression_statement(const std::string& stmt, CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 编译表达式，返回结果寄存器
     */
    size_t compile_expression(const std::string& expr, CompileContext& ctx);
    
    /**
     * @brief 编译表达式并存储到变量
     */
    bool compile_expression_and_store(const std::string& expr, const std::string& var_name, 
                                     CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 编译if语句
     */
    bool compile_if_statement(const std::string& stmt, CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 编译elseif语句
     */
    bool compile_elseif_statement(const std::string& stmt, CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 编译else语句
     */
    bool compile_else_statement(const std::string& stmt, CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 编译endif语句
     */
    bool compile_endif_statement(const std::string& stmt, CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 编译while语句
     */
    bool compile_while_statement(const std::string& stmt, CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 编译endwhile语句
     */
    bool compile_endwhile_statement(const std::string& stmt, CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 添加常量
     */
    size_t add_constant(CompileContext& ctx, const Value& value);
    
    /**
     * @brief 分配寄存器
     */
    size_t allocate_register(CompileContext& ctx, const std::string& var_name = "");
    
    /**
     * @brief 更新行号映射
     */
    void update_line_mapping(CompileContext& ctx, size_t bytecode_offset, size_t source_line);
    
    /**
     * @brief 编译for循环语句
     */
    bool compile_for_statement(const std::string& stmt, CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 编译endfor语句
     */
    bool compile_endfor_statement(const std::string& stmt, CompileContext& ctx, size_t line_num);
    
    /**
     * @brief 编译list字面量 [1, 2, 3]
     */
    size_t compile_list_literal(const std::string& expr, CompileContext& ctx);
    
    /**
     * @brief 编译dict字面量 {"a": 1, "b": 2}
     */
    size_t compile_dict_literal(const std::string& expr, CompileContext& ctx);
};

} // namespace viml